package ui;

import org.jvnet.substance.skin.SubstanceCremeCoffeeLookAndFeel;
import ui.tab.*;
import utils.DBUtil;
import utils.FileUtil;
import utils.StringUtil;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 代码生成器规范代码编写
 * Created by liushun on 2016/11/21.
 */
public class AgCodeMain extends JFrame {

    //配置数据源面板
    private DataSourceConfigTab dsc = null;
    //配置生成参数面板
    private ParamConfigTab pc = null;
    //字段转换设置面板
    private ColumnConverTab cc = null;
    //数据库信息面板
    private DataBaseInfoTab dbi = null;

    //选项卡面板
    private JTabbedPane jTabbedPane = createTabPanel();

    private JButton createBtn = createSubmitButton();

    private JScrollPane jScrollPane = createJScrollPane();


    //公共日志面板
    private static JTextPane jTextPane = null;

    //程序运行路径
    public final static String filePath;

    public static String mainPath;

    //配置文件
    public final static Properties config = new Properties();

    static {
        String projectPath = AgCodeMain.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        try {
            mainPath = URLDecoder.decode(projectPath, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            System.out.println("文件路径转码失败：" + e.getMessage());
        }
        filePath = StringUtil.subLastString(mainPath, "/", 2);
        File file = new File(filePath + File.separator + "config.ini");
        copyFile(new String[]{"config.ini"
                , "ftl/entity.ftl"
                , "ftl/controller.ftl"
                , "ftl/service.ftl"
                , "ftl/serviceImpl.ftl"
                , "ftl/mapper.ftl"
                , "ftl/sqlxml.ftl"});
        try {
            config.load(new FileInputStream(file));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("加载config配置文件出现异常");
        }
    }

    //拷贝配置文件
    private static void copyFile(String... files) {
        for (String file : files) {
            File ftlFile = new File(filePath + File.separator + file);
            if (!ftlFile.exists()) {
                InputStream resourceEntityAsStream = AgCodeMain.class.getResourceAsStream("/" + file);
                FileUtil.copyFile(resourceEntityAsStream, ftlFile.getPath());
            }
        }
    }

    //初始化程序
    public AgCodeMain() {
        this.setTitle("AgCode 代码生成器"); //设置标题
        this.setSize(400, 500); //设置大小
        this.setLocationRelativeTo(null); //居中显示
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //关闭按钮时退出程序
        this.setResizable(false); //不允许改变窗口大小

        JPanel jPanel = new JPanel();
        jPanel.add(jTabbedPane); //添加选项卡
        jPanel.add(createBtn); //添加项目生成按钮
        jPanel.add(jScrollPane); //添加日志文本域
        jPanel.setLayout(null);
        this.add(jPanel);
        this.setVisible(true); //设置显示
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                int ret = JOptionPane.showConfirmDialog(null, "是否确定退出AgCode？", "提示", JOptionPane.OK_OPTION);
                if (ret == JOptionPane.OK_OPTION) {
                    DBUtil.close();
                    dsc.setConfig(); //设置数据源配置参数
                    pc.setConfig();//
                    FileUtil.fileContentModify(AgCodeMain.filePath + "/config.ini", config);
                    System.exit(0);
                }
            }
        });
        this.setLayout(null);
    }


    //初始化选项卡面板
    private JTabbedPane createTabPanel() {
        dsc = new DataSourceConfigTab();
        pc = new ParamConfigTab();
        cc = new ColumnConverTab();
        dbi = new DataBaseInfoTab();
        final JTabbedPane tabbedPane = new JTabbedPane();
        //切换事件
        tabbedPane.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                int selectedIndex = tabbedPane.getSelectedIndex();  //获得选中的选项卡索引
                tabbedPane.setBackgroundAt(selectedIndex, new Color(174, 198, 228));
                //String title = tabbedPane.getTitleAt(selectedIndex);//获得选项卡标签
                if (selectedIndex == 1) {
                    pc.setDbName(dsc.getSjkTxt());
                } else if (selectedIndex == 3) { //加载数据表到该面板
                    dbi.setTableList(dsc.getSjkTxt());
                }
            }
        });
        tabbedPane.add("配置数据源", dsc);
        tabbedPane.add("配置生成参数", pc);
        tabbedPane.add("字段转换设置", cc);
        tabbedPane.add("数据库信息", dbi);
        tabbedPane.add("生成说明", new ReadMeTab());
        tabbedPane.setBounds(0, 0, 400, 320);
        return tabbedPane;
    }

    //项目生成按钮
    private JButton createSubmitButton() {
        createBtn = new JButton("一键生成SSM项目");
        createBtn.setBounds(40, 420, 320, 30);
        createBtn.addActionListener(new CreateProjectActionListenr());
        return createBtn;
    }

    //日志信息显示框
    private JScrollPane createJScrollPane() {
        jTextPane = new JTextPane();
        jTextPane.setText("日志信息....");
        // jTextPane.setFont(new Font("宋体",0 , 11));
        jTextPane.setBackground(new Color(255, 255, 255));
        jTextPane.setSelectedTextColor(Color.RED);
        // jTextPane.setForeground(new Color(0, 128, 0));
        JScrollPane jScrollPane = new JScrollPane(jTextPane);
        JScrollBar verticalScrollBar = jScrollPane.getVerticalScrollBar();
        verticalScrollBar.setPreferredSize(new Dimension(12, 0));
        JScrollBar horizontalScrollBar = jScrollPane.getHorizontalScrollBar();
        verticalScrollBar.setPreferredSize(new Dimension(12, 0));
        horizontalScrollBar.setPreferredSize(new Dimension(0, 12));
        jScrollPane.setBounds(40, 330, 320, 80);
        return jScrollPane;
    }

    /**
     * 控制显示日志信息
     *
     * @param txt      显示日志文本
     * @param color    文本颜色
     * @param isAppend 是否追加
     * @return
     */
    public static void log(String txt, Color color, boolean isAppend) {
        SimpleAttributeSet attrSet = new SimpleAttributeSet();
        StyleConstants.setForeground(attrSet, color);
        if (!isAppend)
            jTextPane.setText("");
        Document doc = jTextPane.getDocument();
        try {
            doc.insertString(doc.getLength(), "\n" + txt, attrSet);
        } catch (BadLocationException e) {
            System.out.println("日志信息显示失败：" + e.getMessage());
        }
    }

    //一件生成最基本的项目
    private class CreateProjectActionListenr implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            createBtn.setEnabled(false);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        long startTime = System.currentTimeMillis();
                        java.util.jar.JarFile file = new JarFile(filePath+File.separator+"AgCode.jar");
                        Enumeration<JarEntry> entrys = file.entries();
                        int count = 0;
                        while(entrys.hasMoreElements()){
                            JarEntry jar = entrys.nextElement();
                            if(jar.getName().indexOf("ssm")!=-1) {
                                InputStream resourceEntityAsStream = AgCodeMain.class.getResourceAsStream("/" + jar.getName());
                                FileUtil.copyFile(resourceEntityAsStream, filePath+"/"+jar.getName());
                                AgCodeMain.log(jar.getName()+" 生成完成!", Color.blue, true);
                            }
                            count++;
                        }
                        file.close();
                        Thread.yield();
                        createBtn.setEnabled(true);
                        JOptionPane.showMessageDialog(null, "共创建了"+count+"个文件，耗时 "+(System.currentTimeMillis()-startTime)+" 毫秒!", "提示", JOptionPane.INFORMATION_MESSAGE);
                    } catch (IOException e) {
                        createBtn.setEnabled(true);
                        JOptionPane.showMessageDialog(null, "生成失败, 没有找到AgCode.jar 或者已经被重新命名!", "提示", JOptionPane.ERROR_MESSAGE);
                        AgCodeMain.log(e.getMessage(), Color.red, true);
                    }
                }
            }).start();
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(new SubstanceCremeCoffeeLookAndFeel());
                    JFrame.setDefaultLookAndFeelDecorated(true);
                    JDialog.setDefaultLookAndFeelDecorated(true);
                    AgCodeMain ag = new AgCodeMain();
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        });

    }
}
